package org.nicocube.airain.domain.server.storable;

import java.util.List;
import java.util.Map;

import javax.jdo.JDOObjectNotFoundException;

import org.nicocube.airain.domain.client.exception.DomainException;
import org.nicocube.airain.domain.client.gamedate.GameDate;
import org.nicocube.airain.domain.client.gamedate.GameDateManager;
import org.nicocube.airain.domain.server.cache.CacheHolder;
import org.nicocube.airain.domain.server.dao.DomainDAO;
import org.nicocube.airain.domain.server.dao.DomainRequest;
import org.nicocube.airain.domain.server.dao.DomainResultContainer;
import org.nicocube.airain.domain.server.dao.PersistenceAccessor;

public class GameDateManagerDAO extends DomainDAO {

	public synchronized GameDateManager getSingleton() throws DomainException {
		GameDateManager singleton;

		Map<Class<GameDateManager>,GameDateManager> cache = CacheHolder.retrieveCache();

		if ( ! cache.containsKey(GameDateManager.class)) {
			DomainResultContainer<GameDateManager> result = new DomainResultContainer<GameDateManager>();
			eval(singletonRequest(result));
			singleton = result.get();

			cache.put(GameDateManager.class, singleton);

		} else {
			singleton=(GameDateManager) cache.get(GameDateManager.class);
		}

		return singleton;
	}

	public void initSingleton() throws DomainException {
		GameDateManager singleton;

		Map<Class<GameDateManager>,GameDateManager> cache = CacheHolder.retrieveCache();

		DomainResultContainer<GameDateManager> result = new DomainResultContainer<GameDateManager>();
		eval(singletonRequest(result));
		singleton = result.get();

		cache.put(GameDateManager.class, singleton);
	}

	/**
	 * 
	 * 
	 * @param result
	 * @return
	 */
	DomainRequest singletonRequest(final DomainResultContainer<GameDateManager> result) {
		return new DomainRequest() {
			@Override
			public void playOn(PersistenceAccessor pm) throws DomainException {
				GameDateManager gameDateManager;
				try {
					List<GameDateManager> result = pm.newQuery(GameDateManager.class).executeList();
					gameDateManager = result.get(0);
				} catch (JDOObjectNotFoundException e) {
					gameDateManager = pm.makePersistent(new GameDateManager(new GameDate(1,1,1,1)));
				} catch (IndexOutOfBoundsException e) {
					gameDateManager = pm.makePersistent(new GameDateManager(new GameDate(1,1,1,1)));
				}
				result.set(gameDateManager);
			}
		};
	}


	public void incCurrentSingleton() throws DomainException {
		Map<Class<GameDateManager>,GameDateManager> cache = CacheHolder.retrieveCache();

		final DomainResultContainer<GameDateManager> result = new DomainResultContainer<GameDateManager>();
		eval(
			singletonRequest(result),
			new DomainRequest() {
				@Override
				public void playOn(PersistenceAccessor pm)
				throws DomainException {
					result.get().incCurrent();
				}
			},
			new DomainRequest() {
				@Override
				public void playOn(PersistenceAccessor pm) throws DomainException {
					pm.refresh(result.get());
				}
			}
		);

		cache.put(GameDateManager.class, result.get());

	}

}
